---
title: Patching
hide_title: true
---

import {
	AdvancedMarkdown,
	Aside,
	BuildConfigTool,
	Badge,
	BuildinfoIntroduction,
	BuildinfoBuildHelp,
	Card,
	CardGrid,
	Charts,
	Details,
	FileTree,
	GithubActions,
	Icon,
	LinkCard,
	Modal,
	Patchinfo,
	Scriptinfo,
	ScriptVersions,
	Steps,
	TabItem,
	Tabs
} from "/src/components/global.jsx"

### Patching summary

The script supports automatic patching of all modules during build with a sophisticated three-method priority system. The patching system works hierarchically to ensure maximum flexibility:

#### Patching Methods (Priority Order)

**Method 1: Source Directory (Highest Priority)**
- Complete source file replacement via `patches/{module}/{version}/source/` directory
- Files are directly copied to the build directory, overwriting existing files
- Most flexible method for extensive modifications

**Method 2: Patch Files (Local)**
- Traditional unified diff patches applied via `git apply` or `patch` command
- Multiple patch sources supported with intelligent merging:
  - `patch` file (primary patch)
  - `url` file (downloads and merges remote patches)
  - `*.patch` and `*.diff` files (merged in alphabetical order)
- Auto-detects git repositories and uses appropriate patching method

**Method 3: Remote Patches (Fallback)**
- Downloads patches from remote GitHub repositories when local patches are empty/missing
- Uses GitHub API for comprehensive directory structure downloads
- Supports both individual files and complete directory trees
- Validates branch names for security

Here is an example local directory structure that the script will use to apply patches to libtorrent `v1.2.19` and qBittorrent `release-5.0.3`

<FileTree>
- qbt-nox-static.bash
- qbt-build/
  - patches/
    - libtorrent/
      - v1.2.19/
        - patch                    # Primary patch file
        - url                      # URL to download remote patch
        - 01.patch                 # Additional patch file
        - 02.diff                  # Additional diff file
        - source/                  # Source directory (highest priority)
          - include/
          - src/
    - qbittorrent/
      - 5.0.3/
        - patch                    # Primary patch file
        - url                      # URL to download remote patch
        - custom.patch             # Additional patch file
        - source/                  # Source directory (highest priority)
          - src/
            - webui/
              - webui.cpp          # Modified source file
</FileTree>

:::tip
Use the help command to get more information

```bash
./qbt.bash -h-pr
```
:::

#### Patch Processing Details

**Multi-Patch Merging:**
- When multiple patches exist, they are intelligently merged into a single unified patch
- Merge order: `patch` file → `url` download → `*.patch`/`*.diff` files (alphabetical)
- Each merged patch is labeled with its source for debugging
- Temporary atomic operations prevent corruption during merging

**Smart Patch Application:**
- Auto-detects if source directory contains a git repository
- Uses `git apply` for git repositories (with validation via `--check`)
- Falls back to traditional `patch -p1` for non-git sources
- Comprehensive error handling and status reporting

**Remote Patch Security:**
- Branch name validation using regex `^[a-zA-Z0-9._-]+$`
- GitHub API integration with proper error handling
- Recursive directory download with JSON parsing validation
- Automatic cleanup of zero-byte failed downloads

:::note
The default remote patch repository `userdocs/qbittorrent-nox-static` stores only critical patches required for successful builds or security fixes.

No customizations or optional patches are stored in the default repository. Any applied remote patch should be considered essential.
:::

### Boot strapping

By default the script installs to a build directory that is a sub directory relative to the script location. This means that if you clone the git repo and run the script it won't find the local patches. There are few ways to handle this.

- **Option 1:** Default, the script assumes you will prepare the environment before building by using the bootstrapping feature. This will create the required directory structure, then you copy the patch files to the correct location as needed.
- **Option 2:** Clone the repo and copy the patches to the correct location

	```bash
	git clone --depth 1 https://github.com/userdocs/qbittorrent-nox-static.git
	cd qbittorrent-nox-static
	mkdir -p qbt-build
	cp -r patches qbt-build/
	```

- **Option 3:** You can set the build dir to the root of the github repo and the script will find the patches

	```bash
	export qbt_build_dir="."
	```
- **Option 4:**
    Upload the patches to a remote github repo with the `patches` dir in the repo root and use the `pr` switch or `qbt_patches_url` env to specify the repo URL. The script will download the patches from the remote location and apply them.
- **Option 5:**
    Do nothing and the script will use the default remote patch repo `userdocs/qbittorrent-nox-static` to apply patches

When bootstrapping the script will create the required directory structure using the current defaults and it will look like this:

<Patchinfo/>

## Local patching examples

### Method 1: Source Directory Method (Recommended)

This is the most flexible method for extensive modifications. Instead of creating patches, you directly modify source files:

:::note
We will assume you are in folder with the `qbt-nox-static.bash` script.
:::

**Step 1:** Bootstrap the patches directory
```bash
./qbt.bash -bs-p
```

**Step 2:** Clone the target repository with the specific version
```bash
git clone --branch release-5.0.3 --depth 1 https://github.com/qbittorrent/qBittorrent.git
```

**Step 3:** Copy the entire source tree to your patch directory
```bash
cp -r qBittorrent/* qbt-build/patches/qbittorrent/5.0.3/source/
```

**Step 4:** Edit files directly in the source directory
```bash
# Edit the file you need to modify
nano qbt-build/patches/qbittorrent/5.0.3/source/src/webui/webui.cpp
```

**Step 5:** Build with your modifications
```bash
./qbt.bash all
```

The script will automatically detect the `source` directory and copy all files to the build location, overwriting the original source.

### Method 2: Traditional Patch File Method

For smaller, targeted changes, traditional patch files are more efficient:

**Step 1:** Bootstrap and prepare source
```bash
./qbt.bash -bs-p
git clone --branch release-5.0.3 --depth 1 https://github.com/qbittorrent/qBittorrent.git
```

**Step 2:** Make a backup and edit the file
```bash
cp qBittorrent/src/webui/webui.cpp webui.cpp.orig
cp qBittorrent/src/webui/webui.cpp webui.cpp
# Edit webui.cpp with your changes
nano webui.cpp
```

**Step 3:** Create the patch file
```bash
diff -Naru webui.cpp.orig webui.cpp > qbt-build/patches/qbittorrent/5.0.3/patch
```

**Step 4:** Build with the patch
```bash
./qbt.bash all
```

### Method 3: Multiple Patch Files

The script supports merging multiple patch files automatically:

```bash
# Place multiple patches in the patch directory
echo "patch content 1" > qbt-build/patches/qbittorrent/5.0.3/01-feature-a.patch
echo "patch content 2" > qbt-build/patches/qbittorrent/5.0.3/02-feature-b.patch
echo "patch content 3" > qbt-build/patches/qbittorrent/5.0.3/99-final-fixes.diff
```

The script will merge all `*.patch` and `*.diff` files in alphabetical order into a single unified patch.

### Method 4: URL-based Patches

Download and apply patches from remote URLs:

```bash
# Create a URL file pointing to a remote patch
echo "https://github.com/qbittorrent/qBittorrent/pull/18271.patch" > qbt-build/patches/qbittorrent/5.0.3/url
```

The script will download and apply the patch automatically during build.

### Using custom github tags

Some modules like libtorrent and qbittorrent have multiple tags that can be used and they can be passed to the script as variables or switches. The script will use the default tags if none are provided.

Using the `-qt` and -`lt` switches here:

```bash
~/qbt.bash -qt master -lt RC_2_0 -bs
```

or

```bash
export qbt_qbittorrent_tag=master
export qbt_libtorrent_tag=RC_2_0
```

The bootstrapped directory structure would look like this instead:

```bash
qbt-build/patches/qbittorrent/master
qbt-build/patches/libtorrent/RC_2_0
```

:::caution
Remember to provide the same tags via switches when using the build command or the patches won't match the defaults.

Only the env variables will persist between uses of the script.
:::

```bash
qbt.bash -qt master -lt RC_2_0 all
```

### Remote GitHub-based patching

The script can automatically download patches from GitHub repositories using the `-pr` switch or `qbt_patches_url` environment variable.

#### Repository Structure

Your patches need to be hosted in a GitHub repository with this structure:

<Tabs>
  <TabItem value="qbittorrent" label="qbittorrent" default>

```bash
patches/qbittorrent/master/patch
patches/qbittorrent/master/url
patches/qbittorrent/master/01-custom.patch
patches/qbittorrent/master/source/src/webui/webui.cpp
patches/qbittorrent/4.5.0/patch
patches/qbittorrent/4.5.0/source/
```

  </TabItem>
  <TabItem value="libtorrent" label="libtorrent">

```bash
patches/libtorrent/RC_2_0/patch
patches/libtorrent/RC_2_0/source/include/
patches/libtorrent/RC_1_2/patch
patches/libtorrent/v1.2.12/url
```

  </TabItem>
</Tabs>

#### Using Remote Patches

**Method 1:** Command line switch
```bash
./qbt.bash all -pr username/repository
```

**Method 2:** Environment variable
```bash
export qbt_patches_url="username/repository"
./qbt.bash all
```

#### Advanced Remote Patch Features

**Recursive Directory Downloads:** The script uses GitHub API to recursively download entire directory structures, including nested `source/` directories and multiple patch files.

**Comprehensive File Support:** Downloads all patch-related files:
- `patch` files (primary patches)
- `url` files (for chained remote patches)
- `*.patch` and `*.diff` files
- Complete `source/` directory trees

**Fallback System:** If GitHub API fails, the script falls back to downloading common patch filenames directly.

### How to make a patch

Using qbittorrent as an example we will edit the `src/base/bittorrent/session.cpp` to apply some session defaults.

Download the relevant git repo:

```bash
git clone --no-tags --single-branch --branch release-4.5.0 --shallow-submodules --recurse-submodules --depth 1 https://github.com/qbittorrent/qBittorrent.git
```

Copy the file that we need to edit to our home directory.

```bash
cp qBittorrent/src/base/bittorrent/session.cpp ~/session.cpp
```

Now edit the `~/session.cpp`. Once you have finished making your changes you can create a patch file using this command

```bash
diff -Naru qBittorrent/src/base/bittorrent/session.cpp ~/session.cpp > ~/patch
```

Then you place that patch file in the matching tag directory.

```bash
patches/qbittorrent/4.3.4.1/patch
```

### Using a Github pull request or commit

First, it's sensible to make sure the patch that we want to use is from a pull request on the same branch that we are building against. So when using `release-4.5.0` we should use https://github.com/qbittorrent/qBittorrent/tree/v4_5_x

You can see the branches for qBittorrent here - https://github.com/qbittorrent/qBittorrent/branches

When you are on a commit or pull request you simply add `.patch` to the end of the url.

So here we take the pull request or commit URL

https://github.com/qbittorrent/qBittorrent/pull/18271

https://github.com/qbittorrent/qBittorrent/commit/c924904308e806db6e1b321da18c1f91c4e8f8bf

and add `.patch` to it so it becomes this

https://github.com/qbittorrent/qBittorrent/pull/18271.patch

https://github.com/qbittorrent/qBittorrent/commit/c924904308e806db6e1b321da18c1f91c4e8f8bf.patch

You can download these using `curl` or `wget` and use these as patches in custom builds.

## Troubleshooting and Best Practices

### Debug Information

The script provides detailed output during patch application:
- **Method Selection:** Shows which patching method is being used
- **File Merging:** Labels each merged patch with its source
- **Application Status:** Reports success/failure of patch operations
- **Git Detection:** Indicates whether git apply or traditional patch is used

### Best Practices

**Patch Organization:**
- Use descriptive filenames for multiple patches (e.g., `01-security-fix.patch`, `02-performance.patch`)
- Keep patches atomic - one logical change per patch file
- Test patches individually before combining

**Source Directory Method:**
- Only include modified files to minimize disk usage
- Maintain directory structure matching the original source
- Consider using git to track your modifications in the source directory

**Remote Patch Security:**
- Always review remote patches before applying
- Use trusted repositories for remote patches
- Consider forking and hosting your own patch repositories

**Version Management:**
- Keep patches aligned with specific module versions
- Test patches when updating module versions
- Document patch purposes and compatibility

### Common Issues

**Patch Application Failures:**
- Check patch format (unified diff with `-Naru` options)
- Verify patch applies to correct source version
- Ensure proper line endings (Unix LF, not Windows CRLF)

**Remote Download Issues:**
- Verify GitHub repository structure matches expected format
- Check network connectivity and GitHub API limits
- Use local patches as fallback for critical builds

### Cache folder based patching

The cache folder system serves as an offline dependency system for storing and modifying source files:

**Advantages:**
- Persistent modifications across builds
- Version-specific source storage via git checkout
- More flexible than patch directory method
- Allows comprehensive source tree modifications

**Usage:**
1. Enable cache folder system in script configuration
2. Modify source files directly in cached directories
3. Files are automatically copied to build directory during compilation

This method complements the patch system and provides another layer of source customization flexibility.
